<template>
  <el-form label-width="100px" action="/xxx">
    <el-form-item label="SPU名称">
      <el-input placeholder="SPU名称" v-model="spuInfo.spuName"></el-input>
    </el-form-item>

    <el-form-item label="品牌">
      <el-select placeholder="请选择品牌" v-model='spuInfo.tmId'>
        <el-option
          v-for="tm in trademarkList"
          :key="tm.id"
          :label="tm.tmName"
          :value="tm.id">
        </el-option>
      </el-select>
    </el-form-item>

    <el-form-item label="SPU描述">
      <el-input type="textarea" placeholder="SPU描述" rows="3" v-model="spuInfo.description"></el-input>
    </el-form-item>
    <el-form-item label="SPU图片">
      <el-upload
        multiple
        :file-list="spuImageList"
        :action="$BASE_API +'/admin/product/fileUpload'"
        list-type="picture-card"
        :on-preview="handlePictureCardPreview"
        :on-remove="handleRemove"
        :on-success="handleAdd">
        <i class="el-icon-plus"></i>
      </el-upload>
      <!-- 显示预览大图 -->
      <el-dialog :visible.sync="dialogVisible">
        <img width="100%" :src="dialogImageUrl" alt="">
      </el-dialog>
    </el-form-item>

    <el-form-item label="销售属性">
      <el-select :placeholder="saleAttrText" v-model="attrId_attrName"> 
        <el-option
          v-for="item in unUseSaleAttrList"
          :key="item.id"
          :label="item.name"
          :value="item.id +'_'+item.name">
        </el-option>
      </el-select>

      <el-button type="primary" icon="el-icon-plus" @click="addSpuSaleAttr" :disabled="!attrId_attrName">添加销售属性</el-button>

      <el-table
        :data="spuInfo.spuSaleAttrList"
        border>
        <el-table-column
          type="index"
          label="序号"
          width="80"
          align="center">
        </el-table-column>

        <el-table-column
          prop="saleAttrName"
          label="属性名"
          width="120">
        </el-table-column>

        <el-table-column
          label="属性值名称列表">
          <template v-slot="{row, $index}">
            <el-tag style="margin-right: 5px;" type="success" v-for="(item, index) in row.spuSaleAttrValueList" 
            :key="item.saleAttrValueName" closable @close="row.spuSaleAttrValueList.splice(index, 1)">{{item.saleAttrValueName}}</el-tag>
            <el-input @blur="addAttrValue(row, $index)" @keydown.enter.prevent.native="addAttrValue(row, $index)" 
              v-model.trim="row.saleAttrValueName" :ref="$index" v-if="row.edit" placeholder="属性值名称" size="small" style="width: 120px"></el-input>
            <el-button v-else size="mini" icon="el-icon-plus" @click="showInput(row, $index)">添加</el-button>
          </template>
        </el-table-column>
        <el-table-column
          label="操作"
          width="120">
          <template v-slot="{row, $index}">
            <hint-button @click.prevent="removeAttr($index)" title="删除" type="danger" size="small" icon="el-icon-delete"></hint-button>
          </template>
        </el-table-column>
      </el-table>
    </el-form-item>

    <el-form-item>
      <el-button type="primary" @click="saveOrUpdate">保存</el-button>
      <el-button @click="cancel">取消</el-button>
    </el-form-item>

  </el-form>
</template>

<script>
export default {
  name: 'SpuForm',
/* 
{
  "category3Id": 61,
  "spuName": "aa",
  "description": "aa描述",
  "tmId": 2,
  "spuSaleAttrList": [
    {
      "baseSaleAttrId": "1",
      "saleAttrName": "选择颜色",
      "spuSaleAttrValueList": [
        {
          "saleAttrValueName": "a",
          "baseSaleAttrId": "1"
        }
      ]
    }
  ],
  "spuImageList": [{
    "imgName": "下载 (1).jpg",
    "imgUrl": "http://47.93.148.192:8080/xxx.jpg"
  }]
}
*/
  data() {
    return {
      dialogImageUrl: '',
      dialogVisible: false,

      spuId: '', // 当前要修改的spuId
      spuInfo: { // 要添加/更新的spu详情信息对象
        // 父组件传入
        category3Id: null, // 三级分类的Id

        // 利用v-model收集
        spuName: null, // 名称
        description: null, // 描述
        tmId: null, // 品牌的id

        spuSaleAttrList: [], // spu的销售属性列表
        spuImageList: [], // spu图片列表
      },
      spuImageList: [], // spu图片列表
      trademarkList: [], // 品牌列表
      saleAttrList: [], // 销售属性列表
      attrId_attrName: '', // 要收集的销售属性id和name    id_name
    };
  },

  computed: {
    /* 
    未使用的销售属性列表
     */
    unUseSaleAttrList () {
      const {saleAttrList, spuInfo:{spuSaleAttrList}} = this   // 对象的嵌套解构
      return saleAttrList.filter(item => {
        /* 
        item
        {
          "id": 1,
          "name": "选择颜色"
        }
        spuSaleAttrList
        [
          {
            "id": 136,
            "spuId": 30,
            "baseSaleAttrId": 1,
            "saleAttrName": "选择颜色",
          }
        ]
        // find() | map() | filter() | reduce() | some() | every()
        */
        return !spuSaleAttrList.some(attr => attr.saleAttrName===item.name) // 如果有一个对应的那不留下来
      })
    },

    saleAttrText () {
      return this.unUseSaleAttrList.length>0 ? `还有${this.unUseSaleAttrList.length}可选择` : '没有啦!'
    },
  },

  methods: {

    cancel () {
      this.$emit('cancel')
      this.resetData()
    },

    /* 
    添加/更新spu
    */
    async saveOrUpdate () {
      // 得到请求提交的数据
      const spuInfo = this.spuInfo
      // 在发请求前: 需要对数据进行处理/整理的操作
      /* 
      处理1: spuImageList
        目标: 
          {
            "imgName": "下载 (1).jpg",
            "imgUrl": "http://47.93.148.192:8080/xxx.jpg"
          }
        原本有的:
          {
            name: '',
            url: ''
          }
        新上传的:
          {
            name: '',
            response: {data: url值}
          }
      */
      spuInfo.spuImageList = this.spuImageList.map(item => ({
        imgName: item.name,
        imgUrl: item.response ? item.response.data : item.url
      }))

      /* 
      处理2: 删除一些不必要提交的数据
        没有一个属性值的属性  spuSaleAttrValueList数组是空的   ==> 过滤掉
        edit属性  删除属性
      */
     spuInfo.spuSaleAttrList = spuInfo.spuSaleAttrList.filter(item => {
       if (item.spuSaleAttrValueList.length>0) {
         delete item.edit
         return true
       }
       return false
     })

      // 发请求
      await this.$API.spu.addUpdate(spuInfo)

      // 请求成功做相应处理
      this.$message.success('操作成功了!')

      // 通知父组件
      this.$emit('success')

      // 清除数据
      this.resetData()
    },

    /* 
    重置数据
    */
    resetData () {
      this.dialogImageUrl = ''
      this.dialogVisible = false

      this.spuId = '' // 当前要修改的spuId
      this.spuInfo = { // 要添加/更新的spu详情信息对象
        // 父组件传入
        category3Id: null, // 三级分类的Id

        // 利用v-model收集
        spuName: null, // 名称
        description: null, // 描述
        tmId: null, // 品牌的id

        spuSaleAttrList: [], // spu的销售属性列表
        spuImageList: [], // spu图片列表
      }
      this.spuImageList = [] // spu图片列表
      this.trademarkList = [] // 品牌列表
      this.saleAttrList = [] // 销售属性列表
      this.attrId_attrName = ''
    },

    /* 
    添加Spu销售属性
    */
    addSpuSaleAttr () {
      // 拆解出收集销售属性的id和name
      const [baseSaleAttrId, saleAttrName] = this.attrId_attrName.split('_')
      /* 
      向spuInfo.spuSaleAttrList中添加spu销售属性对象
      {
          "baseSaleAttrId": "1",
          "saleAttrName": "选择颜色",
          "spuSaleAttrValueList": [],
          // edit: true
        }
      */
      this.spuInfo.spuSaleAttrList.push({
        baseSaleAttrId,
        saleAttrName,
        spuSaleAttrValueList: [], // 用于保存spu销售属性值
      })

      // 清除收集的数据
      this.attrId_attrName = null
    },

    /* 
    删除SPU销售属性
    */
    removeAttr (index) {
      console.log('removeAttr', index)
      this.spuInfo.spuSaleAttrList.splice(index, 1)
    },

    /* 
    添加spu销售属性值
    */
    addAttrValue (row, index) {

      if (row.flag) { // 如果为true代表是紧跟的第二次, 直接结束
        delete row.flag  // 为下一次能正常进入
        return 
      }

      console.log('addAttrValue', row.edit)

      const {spuSaleAttrValueList, saleAttrValueName, baseSaleAttrId} = row

      // 如果没有输入, 直接变为查看模式, 不添加
      if (saleAttrValueName==='') {
        row.edit = false
        return
      }

      // 如果重复了, 添加, 提示重复, 不变为查看模式
      // spuSaleAttrValueList中有没有一个属性值对象的名称与saleAttrValueName相同 ==> 有则为重复
      const isRepeat = spuSaleAttrValueList.some(item => item.saleAttrValueName===saleAttrValueName)
      if (isRepeat) {
        row.flag = true  // 标识已经执行过一次了
        this.$message.warning('输入重复了!')
        this.$refs[index].focus()
        return
      }

      // 向row.spuSaleAttrValueList中添加属性值对象
      spuSaleAttrValueList.push({
        saleAttrValueName, // 输入的名称
        baseSaleAttrId, // row.baseSaleAttrId
      })

      // 显示按钮
      row.edit = false

      // 清除收集的输入数据
      row.saleAttrValueName = ''
    },

    /* 
    显示输入框
    */
    showInput(row, index) {
      // 给row添加/指定edit属性, 且值为true  ==> 显示input
      if (row.hasOwnProperty('edit')) {
        row.edit = true
      } else {
        this.$set(row, 'edit', true)
      }
      // 让input获得焦点  ==> 一定要在显示input之后 ==> 使用$nextTick()
      this.$nextTick(() => this.$refs[index].focus())
    },

    /* 
    初始化加载更新界面所需要数据
    根据spuId获取SpuInfo:  spu.get(spuId)
    根据spuId获取SpuImageList: sku.getSpuImageList(spuId)
    获取所有品牌的trademarkList: trademark.getList()
    获取所有销售属性的saleAttrList: spu.getSaleAttrList()
    */
    initUpdateData (spuId) {
      this.spuId = spuId
      this.getSpuInfo()
      this.getSpuImageList()
      this.getTrademarkList()
      this.getSaleAttrList()
    },

    /* 
    初始化加载添加界面所需要数据
    获取所有品牌的trademarkList: trademark.getList()
	  获取所有销售属性的saleAttrList: spu.getSaleAttrList()
    */
    initAddData (category3Id) {
      // 将category3Id保存spuInfo中
      this.spuInfo.category3Id = category3Id

      this.getTrademarkList()
      this.getSaleAttrList()
    },


    /* 
    根据spuId获取SpuInfo:  spu.get(spuId)
    */
    async getSpuInfo () {
      const result = await this.$API.spu.get(this.spuId)
      const spuInfo = result.data
      this.spuInfo = spuInfo
    },

    /* 
    根据spuId获取SpuImageList: sku.getSpuImageList(spuId)
    */
    async getSpuImageList () {
      const result = await this.$API.sku.getSpuImageList(this.spuId)
      // => 基本作用是定义匿名函数, 还有可能代表return(后面紧跟的不是大括号)
      // 如果需要利用=>返回一个对象时, 需要在对象大括号外面包一个小括号
      const spuImageList = result.data.map(item => ({name: item.imgName, url: item.imgUrl}))
      /* 
      有时需要对请求获取的数据进行特定整理的操作(在保存到data中之前), 如: spuImageList
      当前结构: {imgName, imgUrl}
      目标结构: {name, url}
      */

      this.spuImageList = spuImageList
    },

    /* 
    获取所有品牌的trademarkList: trademark.getList()
    */
    async getTrademarkList () {
      const result = await this.$API.trademark.getList()
      const trademarkList = result.data
      this.trademarkList = trademarkList
    },

    /* 
    获取所有销售属性的saleAttrList: spu.getSaleAttrList()
    */
    async getSaleAttrList () {
      const result = await this.$API.spu.getSaleAttrList()
      const saleAttrList = result.data
      this.saleAttrList = saleAttrList
    },

    /* 
    点击删除按钮的回调
    file: 被删除的图片对象
    fileList: 剩余的所有图片对象的数组
    */
    handleRemove(file, fileList) {
      // 更新SpuImageList
      this.spuImageList = fileList
    },

    /* 
    上传成功后的回调
    file: 上传的图片对象
    fileList: 添加后的所有图片对象的数组
    */
    handleAdd (response, file, fileList) {
      // 更新SpuImageList
      this.spuImageList = fileList
    },

    /* 
    处理显示预览大图图标的事件回调
    */
    handlePictureCardPreview(file) {
      // 将图片url保存到data上
      this.dialogImageUrl = file.url
      // 显示dialog
      this.dialogVisible = true
    },

    
  }
}
</script>

<style scoped>

</style>
